package com.schoolpro.service.impl;


import com.schoolpro.exception.CategoryPropertyException;
import com.schoolpro.exception.ParamValidationException;
import com.schoolpro.exception.PropertyException;
import com.schoolpro.mapper.CategoryMapper;
import com.schoolpro.mapper.CategoryPropertyMapper;
import com.schoolpro.mapper.ItemMapper;
import com.schoolpro.mapper.ValueMapper;
import com.schoolpro.pojo.DO.CategoryDO;
import com.schoolpro.pojo.DO.ItemDO;
import com.schoolpro.pojo.DO.PropertyDO;
import com.schoolpro.pojo.DO.ValueDO;
import com.schoolpro.pojo.DTO.CategoryAddDTO;
import com.schoolpro.pojo.DTO.CategoryUpdateDTO;
import com.schoolpro.pojo.DTO.PropertyDTO;
import com.schoolpro.pojo.DTO.ValueDTO;
import com.schoolpro.pojo.VO.CategoryWithPropertyVO;
import com.schoolpro.pojo.VO.PropertyVO;
import com.schoolpro.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
* @author : Hinton
* @时间 : 1月 22 22:31
*/

@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private CategoryPropertyMapper propertyMapper;
    @Autowired
    private ValueMapper valueMapper;
    @Autowired
    private ItemMapper itemMapper;

    /**
     * 添加类目及几个属性
     * @param categoryAddDTO
     */
    @Override
    @Transactional
    public void addCategory(CategoryAddDTO categoryAddDTO) {
        if (categoryAddDTO.getProperty() == null || categoryAddDTO.getProperty().isEmpty()) {
            throw new CategoryPropertyException("属性为空");
        }

        // 查重
        CategoryDO categoryDO = categoryMapper.getByName(categoryAddDTO.getName(), categoryAddDTO.getNameCn());
        if (categoryDO != null) {
            throw new ParamValidationException("类目已存在");
        }

        categoryDO = new CategoryDO();
        BeanUtils.copyProperties(categoryAddDTO, categoryDO);

        // 插入类目
        categoryMapper.insert(categoryDO);

        // 插入属性
        List<PropertyDO> categoryPropertyDOList = new ArrayList<>();
        for (PropertyDTO propertyDTO : categoryAddDTO.getProperty()) {
            PropertyDO propertyDO = new PropertyDO();
            BeanUtils.copyProperties(propertyDTO, propertyDO);
            // propertyDTO.setCategoryId(categoryDO.getId());
            propertyDO.setGmtCreate(LocalDateTime.now());
            propertyDO.setGmtModified(LocalDateTime.now());
            propertyDO.setCategoryName(categoryDO.getName());

            // 可枚举 - 插入value 枚举值
            if (propertyDO.getEnumerable() == 1) {
                List<ValueDO> valueDOList = new ArrayList<>();
                for (ValueDTO valueDTO : propertyDTO.getEnumValues()) {
                    ValueDO valueDO = new ValueDO();
                    valueDO.setCategoryName(categoryDO.getName());
                    valueDO.setPropertyName(propertyDTO.getName());
                    valueDO.setFieldValue(valueDTO.getFieldValue());
                    valueDO.setComments(valueDTO.getComments());

                    valueDOList.add(valueDO);
                }

                // 批量插入value
                valueMapper.insertBatch(valueDOList);
            } else if (propertyDO.getEnumerable() == 0) {
                // 没有枚举值, 但如果长度 != 0
                if (!propertyDTO.getEnumValues().isEmpty()) {
                    log.info("枚举值异常");
                    throw new PropertyException("不应有枚举值");
                }
            }
            categoryPropertyDOList.add(propertyDO);
        }
        propertyMapper.insertBatch(categoryPropertyDOList);


    }

    @Override
    public void deleteCategory(List<Integer> ids) {
        categoryMapper.deleteCategory(ids);

    }

    /**
     * 修改类目名称, 将category表和property表一起修改
     * @param categoryUpdateDTO
     */
    @Override
    @Transactional
    public void updateCategory(CategoryUpdateDTO categoryUpdateDTO) {
        // 1. 获得类目
        CategoryDO categoryDO = categoryMapper.getById(categoryUpdateDTO.getId());
        // 2. 删除旧的
        // 2.1 删除属性
        propertyMapper.deleteByCategoryName(categoryDO.getName());
        // 2.2 删除value
        valueMapper.deleteByCategoryName(categoryDO.getName());

        // 3. 修改
        // 3.1 修改类目
        categoryMapper.updateCategory(categoryUpdateDTO);
        // 3.2 增加 property value
        List<PropertyDO> propertyDOList = new ArrayList<>();
        for (PropertyDTO propertyDTO : categoryUpdateDTO.getPropertyDTOList()) {
            PropertyDO propertyDO = new PropertyDO();
            BeanUtils.copyProperties(propertyDTO, propertyDO);
            propertyDO.setGmtCreate(LocalDateTime.now());
            propertyDO.setGmtModified(LocalDateTime.now());
            propertyDO.setCategoryName(categoryDO.getName());

            // 可枚举 - 插入value 枚举值
            if (propertyDO.getEnumerable() == 1) {
                List<ValueDO> valueDOList = new ArrayList<>();
                for (ValueDTO valueDTO : propertyDTO.getEnumValues()) {
                    ValueDO valueDO = new ValueDO();

                    valueDO.setGmtCreate(LocalDateTime.now());
                    valueDO.setGmtModified(LocalDateTime.now());
                    valueDO.setCategoryName(categoryDO.getName());
                    valueDO.setPropertyName(propertyDTO.getName());
                    valueDO.setFieldValue(valueDTO.getFieldValue());
                    valueDO.setComments(valueDTO.getComments());

                    valueDOList.add(valueDO);
                }

                // 批量插入value
                valueMapper.insertBatch(valueDOList);
            } else if (propertyDO.getEnumerable() == 0) {
                // 没有枚举值, 但如果长度 != 0
                if (!propertyDTO.getEnumValues().isEmpty()) {
                    throw new PropertyException("不应有枚举值");
                }
            }

            propertyDOList.add(propertyDO);
        }

        propertyMapper.insertBatch(propertyDOList);

        // 3.3 修改item表结构
        itemMapper.updateStructure(categoryDO.getName(), categoryUpdateDTO.getName());

        // todo 3.4 修改unique表
    }

    /**
     * 获取类目属性
     * @param id
     * @return
     */
    @Override
    public CategoryWithPropertyVO getCategoryWithProperty(Integer id) {
        CategoryDO categoryDO = categoryMapper.getById(id);
        if (categoryDO == null) {
            throw new CategoryPropertyException("类目不存在");
        }
        List<PropertyVO> propertyVOList = new ArrayList<>();
        List<PropertyDTO> propertyDOList = propertyMapper.getByCategoryName(categoryDO.getName());
        propertyDOList.forEach(propertyDO -> {
            PropertyVO propertyVO = new PropertyVO();
            BeanUtils.copyProperties(propertyDO, propertyVO);

            // 查枚举值
            if (propertyDO.getEnumerable() == 1) {
                List<ValueDTO> enumValuesList =  valueMapper.getByCategoryPropertyName(categoryDO.getName(), propertyDO.getName());

                propertyVO.setEnumValues(enumValuesList);
            }

            propertyVOList.add(propertyVO);

        });

        return new CategoryWithPropertyVO(categoryDO.getId(), categoryDO.getName(), propertyVOList);
    }
}
